library(tidyverse)
library(lubridate)
library(glue)
library(here)
library(ggtext)
library(patchwork)
library(kableExtra)
library(hrbrthemes)
library(tidytext)
library(wordcloud)
source(here("src/5-funcao-limpando-texto.R"))
set.seed(1014)

knitr::knit_hooks$set(inline = function(x) prettyNum(x, big.mark = ".", decimal.mark = ","))

options(
  digits = 1,
  scipen = 999,
  OutDec = ",",
  knitr.kable.NA = "",
  radian.auto_match = FALSE
)

Sys.setenv(LANGUAGE = "pt-br")
Sys.setlocale("LC_TIME", "pt_BR")
#> [1] ""

# helper
`%notin%` <- function(x, y) !(x %in% y)
# aplica identidade visual da TB/AeP:
source(here("src/0-paleta-de-cores.R"), encoding = "utf-8")

Análises de pedidos de acesso a informação via LAI considerando a decisão de acesso.

Atenção!

Atenção: Eu fiz os agrupamentos para visualizar os órgãos de maneira mais focada, mas os critérios apenas intuitivos e baseados nos próprios nomes dos órgãos.

Atenção: a análise das núvens de palavras contemplam somente o período de 2015 até 2021, pois antes disso a base de dados não é disponibilizada pela CGU

pedidos_painel <- "dados/load/rds/base-cgu.rds" %>%
  here() %>%
  readRDS() %>%
  pluck("pedidos") %>%
  janitor::clean_names() %>% 
  mutate(
    ts_registro = data_registro,
    ts_resposta = data_resposta,
    data_registro = dmy(data_registro) %>% floor_date(unit = "month"),
    data_resposta = dmy(data_resposta) %>% floor_date(unit = "month")) %>% 
  rename(orgao = orgao_destinatario) %>%
  filter(!is.na(decisao),
         !is.na(data_resposta),
         data_registro < ymd("2021-10-01"), 
         esfera == "Federal")

pedidos_clean <- "dados/load/rds/pedidos-clean.rds" %>% 
  here() %>% 
  readRDS()
orgaos_count_decisao <- pedidos_painel %>%
  select(id_pedido, data_registro, decisao, orgao) %>%
  add_count(data_registro, name = "n_mes") %>%
  add_count(data_registro, orgao, name = "n_mes_orgao") %>%
  add_count(data_registro, decisao, name = "n_mes_decisao") %>%
  add_count(data_registro, decisao, orgao, name = "n_mes_decisao_orgao") %>% 
  select(id_pedido:n_mes, n_mes_decisao, n_mes_orgao, n_mes_decisao_orgao)

wafflechart_acesso_negado <- function(df, x, 
  titulo = "Maiores taxas de acessos negados registrada em um ano, por órgão") {
  
  df %>%
    filter(str_detect(orgao, x), decisao == "Acesso Negado") %>% 
    mutate(
      taxa_interna = n_mes_decisao_orgao / n_mes_orgao,
      taxa_global = n_mes_decisao_orgao / n_mes_decisao
    ) %>% 
    group_by(orgao) %>% 
    ungroup() %>% 
    group_by(ano = year(data_registro),
             orgao) %>% 
    summarise(
      `Taxa interna máxima registrada em um ano` = max(taxa_interna, na.rm = T),
      `Taxa global máxima registrada em um ano` = max(taxa_global, na.rm = T),
      .groups = "drop"
    ) %>% 
    pivot_longer(-c(ano, orgao), names_to = "categoria", values_to = "valor") %>%
    complete(ano, orgao, categoria) %>% 
    filter(categoria == "Taxa interna máxima registrada em um ano") %>% 
    ggplot(aes(
      x = factor(ano),
      y = reorder(orgao, valor, na.rm = T),
      fill = valor
    )) +
    geom_tile(color = "gray80") +
    geom_text(
      data = . %>% 
        filter(valor >= .15 | (valor >= .1 & str_detect(orgao, "^MEC "))),
      aes(label = scales::percent(valor, accuracy = 0.1, decimal.mark = ",")),
      size = 3) +
    scale_x_discrete(position = "top") +
    scale_fill_gradientn(
      colors = c("white", cores_aep[["laranja"]], cores_aep[["rosa"]]),
      na.value = "gray90",
      labels = scales::percent_format()
    ) +
    theme_minimal() +
    theme(
      panel.grid = element_blank(),
      legend.position = "top",
      legend.direction = "horizontal",
      legend.justification = "left"
    ) +
    labs(
      title = titulo,
      subtitle = glue(
        "Valor máximo registrado no ano de referência (% ao total de pedidos recebidos)"
      ),
      x = NULL,
      y = NULL,
      fill = "%"
    )

}
militares <- "^(CEX|CMAR|COMAER)"
ministerio <- "Ministério|^(CGU|CC-PR|SEGOV|SGPR|AGU|GSI|VPR|PR )"
empresa_publica <- "Ltda$|S\\.A\\.?$|Empresa|Companhia"
educacao <- "Universidade|Escola|Colégio|Instituto Federal de Educação|^CEFET"
saude <- "EBSERH|Hospital|Maternidade"
bancos <- "^(BB|CEF|CMB)\\s|Banco"
cultura <- c(
  "ANCINE",
  "FBN",
  "FCP",
  "FUNARTE",
  "FCRB",
  "IPHAN",
  "FUNDAJ"
) %>% paste(collapse = "|")
cultura <- glue("^({cultura})\\s|Museu")

meio_ambiente <- c(
  "MMA",
  "FUNAI",
  "ICMBio",
  "IBAMA",
  "INCRA",
  "FCP",
  "INPE-MCT",
  "INPA"
) %>% paste(collapse = "|")
meio_ambiente <- glue("^({meio_ambiente})\\s")

ciencia <- c(
  "AEB",
  "CAPES",
  "CNPQ",
  "FINEP",
  "FNDE",
  "CBPF",
  "JBRJ",
  "CETEM",
  "CETENE",
  "CNEN",
  "INT",
  "LNCC-MCT",
  "ON-MCT",
  "LNA",
  "INPI",
  "ITI",
  "INPE-MCT",
  "IBICT",
  "CTI",
  "IPEA",
  "FIOCRUZ",
  "IBC",
  "IBGE",
  "INEP",
  "INES",
  "INSA",
  "FUNDACENTRO",
  "FUNASA"
) %>% paste(collapse = "|")
ciencia <- glue("^({ciencia})\\s")

agencias_reguladoras <- c(
  "INMETRO",
  "ANA(C|TEL)?",
  "ANEEL",
  "ANTAQ",
  "ANTT",
  "ANP",
  "ANM",
  "ANPD",
  "ANS",
  "ANVISA",
  "CADE",
  "COAF",
  "CVM",
  "SERPRO"
) %>% paste(collapse = "|")
agencias_reguladoras <- glue("^({agencias_reguladoras})\\s")


pedidos_painel %>% distinct(orgao) %>% 
  arrange(orgao) %>% 
  filter(
    !str_detect(orgao, educacao),
    !str_detect(orgao, saude),
    !str_detect(orgao, militares),
    !str_detect(orgao, ministerio),
    !str_detect(orgao, empresa_publica),
    !str_detect(orgao, bancos),
    !str_detect(orgao, cultura),
    !str_detect(orgao, meio_ambiente),
    !str_detect(orgao, ciencia),
    !str_detect(orgao, agencias_reguladoras)
  ) %>% print(n = Inf)
#> # A tibble: 18 x 1
#>    orgao                                                                        
#>    <chr>                                                                        
#>  1 AN – Arquivo Nacional                                                        
#>  2 DEPEN – Departamento Penitenciário Nacional                                  
#>  3 DNIT – Departamento Nacional de Infraestrutura de Transportes                
#>  4 DNOCS – Departamento Nacional de Obras Contra as Secas                       
#>  5 DPF – Departamento de Polícia Federal                                        
#>  6 DPRF – Departamento de Polícia Rodoviária Federal                            
#>  7 DPU – Defensoria Pública da União                                            
#>  8 FUNAG – Fundação Alexandre de Gusmão                                         
#>  9 FUNPRESP  - Fundação de Previdência Complementar do Servidor Público Federal~
#> 10 IMBEL – Indústria de Material Bélico do Brasil                               
#> 11 INSS – Instituto Nacional do Seguro Social                                   
#> 12 Órgão para Teste -  pedidos endereçados a esse órgão não serão respondidos/r~
#> 13 PREVIC – Superintendência Nacional de Previdência Complementar               
#> 14 SUDAM – Superintendência do Desenvolvimento da Amazônia                      
#> 15 SUDECO – Superintendência de Desenvolvimento do Centro-Oeste                 
#> 16 SUDENE – Superintendência do Desenvolvimento do Nordeste                     
#> 17 SUFRAMA – Superintendência da Zona Franca de Manaus                          
#> 18 SUSEP – Superintendência de Seguros Privados

Órgãos militares

orgaos_count_decisao %>%
  wafflechart_acesso_negado(militares)

CEX - Comando do Exército

orgao <- pedidos_painel %>%
  filter(str_detect(orgao, "^CEX")) %>% 
  select(id_pedido, data_registro, ano, orgao, 
         assunto_pedido, decisao, especificacao_decisao,
         sub_assunto_pedido) %>% 
  mutate(especificacao_decisao = replace_na(especificacao_decisao, "Não especificada"))

orgao %>% 
  filter(decisao == "Acesso Negado") %>%
  count(ano, assunto_pedido, decisao, especificacao_decisao) %>% 
  add_count(assunto_pedido, wt = n) %>% 
  filter(nn > 10) %>% 
  ggplot(aes(x = reorder(especificacao_decisao, n),
             y = n,
             fill = reorder(assunto_pedido, nn))) +
  #scale_fill_manual(values = pal) +
  labs(
    title = "Acessos negados por assunto e especificação da decisão",
    subtitle = str_glue("{unique(orgao$orgao)}"),
    fill = "Assunto do pedido",
    y = "Quantidade",
    x = "Especificação da decisão"
  ) +
  geom_col() +
  coord_flip()

wordcloud_cex <- function(df, decisao_pedido, campo) {
  
  cor <- if_else(campo == "resposta_clean", cores_aep[2], cores_tb[5])
  titulo <- if_else(
    campo == "resposta_clean", 
    "Frequência de palavras na resposta",
    "Frequência de palavras no pedido"
  )
  
  layout(matrix(c(1, 2), nrow = 2), heights = c(.5, 6))
  par(mar = rep(0, 4))
  plot.new()
  text(x = 0.5, y = 0.5, titulo)
  
  pedidos_clean %>% 
    filter(id_pedido %in% orgao$id_pedido) %>% 
    inner_join(orgao) %>% 
    filter(decisao == "Acesso Negado") %>%
    filter(especificacao_decisao == decisao_pedido) %>% 
    select(
      "id_pedido",
      all_of(campo),
      "data_registro",
      "ano",
      "orgao",
      "assunto_pedido",
      "decisao",
      "especificacao_decisao",
      "sub_assunto_pedido"
    ) %>% 
    unnest_tokens(word, campo) %>% 
    anti_join(stopwords) %>% 
    mutate(word = str_extract(word, "[a-z']+"),
           word = if_else(word == "urltag", "link-url", word)) %>% 
    filter(word != "ddmmyyyy",
           word != "art",
           word != "nup",
           word != "www",
           word != "quot",
           !str_count(word) %in% c(1, 2)) %>% 
    count(word, sort = T) %>% 
    with(wordcloud(word, n, max.words = 150, scale = c(3, .5), 
            random.order = F,
            random.color = F,
             main = title,
            colors = c(cores_tb[["cinza_claro"]],
                       cores_aep[["laranja"]],
                       cor)))

}
CEX - Negativa justificada como “Pedido desproporcional ou desarrazoado”
wordcloud_cex(pedidos_clean, "Pedido desproporcional ou desarrazoado", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido desproporcional ou desarrazoado", "resposta_clean")

CEX - Negativa justificada como “Dados pessoais”
wordcloud_cex(pedidos_clean, "Dados pessoais", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Dados pessoais", "resposta_clean")

CEX - Negativa justificada como “Pedido genérico”
wordcloud_cex(pedidos_clean, "Pedido genérico", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido genérico", "resposta_clean")

CMAR - Comando da Marinha

orgao <- pedidos_painel %>%
  filter(str_detect(orgao, "^CMAR")) %>% 
  select(id_pedido, data_registro, ano, orgao, 
         assunto_pedido, decisao, especificacao_decisao,
         sub_assunto_pedido) %>% 
  mutate(especificacao_decisao = replace_na(especificacao_decisao, "Não especificada"))

orgao %>% 
  filter(decisao == "Acesso Negado") %>%
  count(ano, assunto_pedido, decisao, especificacao_decisao) %>% 
  add_count(assunto_pedido, wt = n) %>% 
  filter(nn > 10) %>% 
  ggplot(aes(x = reorder(especificacao_decisao, n),
             y = n,
             fill = reorder(assunto_pedido, nn))) +
  #scale_fill_manual(values = pal) +
  labs(
    title = "Acessos negados por assunto e especificação da decisão",
    subtitle = str_glue("{unique(orgao$orgao)}"),
    fill = "Assunto do pedido",
    y = "Quantidade",
    x = "Especificação da decisão"
  ) +
  geom_col() +
  coord_flip()

CMAR - Negativa justificada como “Dados pessoais”
wordcloud_cex(pedidos_clean, "Dados pessoais", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Dados pessoais", "resposta_clean")

CMAR - Negativa justificada como “Pedido incompreensível”
wordcloud_cex(pedidos_clean, "Pedido incompreensível", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido incompreensível", "resposta_clean")

CMAR - Negativa justificada como “Pedido genérico”
wordcloud_cex(pedidos_clean, "Pedido genérico", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido genérico", "resposta_clean")

CMAR - Negativa justificada como “Pedido desproporcional ou desarrazoado”
wordcloud_cex(pedidos_clean, "Pedido desproporcional ou desarrazoado", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido desproporcional ou desarrazoado", "resposta_clean")

CMAR - Negativa justificada como “Pedido exige tratamento adicional de dados”
wordcloud_cex(pedidos_clean, "Pedido exige tratamento adicional de dados", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido exige tratamento adicional de dados", "resposta_clean")

CMAR - Negativa justificada como “Informação sigilosa de acordo com legislação específica”
wordcloud_cex(pedidos_clean, "Informação sigilosa de acordo com legislação específica", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Informação sigilosa de acordo com legislação específica", "resposta_clean")

CMAR - Negativa justificada como “Informação sigilosa classificada conforme a Lei 12.527/2011”
wordcloud_cex(pedidos_clean, "Informação sigilosa classificada conforme a Lei 12.527/2011", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Informação sigilosa classificada conforme a Lei 12.527/2011", "resposta_clean")

CMAR - Negativa justificada como “Processo decisório em curso”
wordcloud_cex(pedidos_clean, "Processo decisório em curso", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Processo decisório em curso", "resposta_clean")

COMAER - Comando da Aeronáutica

orgao <- pedidos_painel %>%
  filter(str_detect(orgao, "^COMAER")) %>% 
  select(id_pedido, data_registro, ano, orgao, 
         assunto_pedido, decisao, especificacao_decisao,
         sub_assunto_pedido) %>% 
  mutate(especificacao_decisao = replace_na(especificacao_decisao, "Não especificada"))

orgao %>% 
  filter(decisao == "Acesso Negado") %>%
  count(ano, assunto_pedido, decisao, especificacao_decisao) %>% 
  add_count(assunto_pedido, wt = n) %>% 
  filter(nn > 10) %>% 
  ggplot(aes(x = reorder(especificacao_decisao, n),
             y = n,
             fill = reorder(assunto_pedido, nn))) +
  #scale_fill_manual(values = pal) +
  labs(
    title = "Acessos negados por assunto e especificação da decisão",
    subtitle = str_glue("{unique(orgao$orgao)}"),
    x = "Assunto do pedido",
    y = "Quantidade",
    fill = "Especificação da decisão"
  ) +
  geom_col() +
  coord_flip()

CMAR - Negativa justificada como “Dados pessoais”
wordcloud_cex(pedidos_clean, "Dados pessoais", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Dados pessoais", "resposta_clean")

CMAR - Negativa justificada como “Pedido incompreensível”
wordcloud_cex(pedidos_clean, "Pedido incompreensível", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido incompreensível", "resposta_clean")

COMAER - Negativa justificada como “Pedido genérico”
wordcloud_cex(pedidos_clean, "Pedido genérico", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido genérico", "resposta_clean")

COMAER - Negativa justificada como “Pedido desproporcional ou desarrazoado”
wordcloud_cex(pedidos_clean, "Pedido desproporcional ou desarrazoado", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido desproporcional ou desarrazoado", "resposta_clean")

COMAER - Negativa justificada como “Pedido exige tratamento adicional de dados”
wordcloud_cex(pedidos_clean, "Pedido exige tratamento adicional de dados", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Pedido exige tratamento adicional de dados", "resposta_clean")

COMAER - Negativa justificada como “Informação sigilosa de acordo com legislação específica”
wordcloud_cex(pedidos_clean, "Informação sigilosa de acordo com legislação específica", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Informação sigilosa de acordo com legislação específica", "resposta_clean")

COMAER - Negativa justificada como “Informação sigilosa classificada conforme a Lei 12.527/2011”
wordcloud_cex(pedidos_clean, "Informação sigilosa classificada conforme a Lei 12.527/2011", "detalhamento_solicitacao_clean")

wordcloud_cex(pedidos_clean, "Informação sigilosa classificada conforme a Lei 12.527/2011", "resposta_clean")